"use strict";
var UNIT_BASE = 1000;
var MAX_LEN = 3;
var Unit;
(function(a) {
    a[a["zero"] = 0] = "zero";
    a[a["A"] = 1] = "A";
    a[a["B"] = 2] = "B";
    a[a["C"] = 3] = "C";
    a[a["D"] = 4] = "D";
    a[a["E"] = 5] = "E";
    a[a["F"] = 6] = "F";
    a[a["G"] = 7] = "G";
    a[a["H"] = 8] = "H";
    a[a["I"] = 9] = "I";
    a[a["J"] = 10] = "J";
    a[a["K"] = 11] = "K";
    a[a["L"] = 12] = "L";
    a[a["M"] = 13] = "M";
    a[a["N"] = 14] = "N";
    a[a["O"] = 15] = "O";
    a[a["P"] = 16] = "P";
    a[a["Q"] = 17] = "Q";
    a[a["R"] = 18] = "R";
    a[a["S"] = 19] = "S";
    a[a["T"] = 20] = "T";
    a[a["U"] = 21] = "U";
    a[a["V"] = 22] = "V";
    a[a["W"] = 23] = "W";
    a[a["X"] = 24] = "X";
    a[a["Y"] = 25] = "Y";
    a[a["Z"] = 26] = "Z";
    a[a["AA"] = 27] = "AA";
    a[a["BB"] = 28] = "BB";
    a[a["CC"] = 29] = "CC";
    a[a["DD"] = 30] = "DD";
    a[a["EE"] = 31] = "EE";
    a[a["FF"] = 32] = "FF";
    a[a["GG"] = 33] = "GG";
    a[a["HH"] = 34] = "HH";
    a[a["II"] = 35] = "II";
    a[a["JJ"] = 36] = "JJ";
    a[a["KK"] = 37] = "KK";
    a[a["LL"] = 38] = "LL";
    a[a["MM"] = 39] = "MM";
    a[a["NN"] = 40] = "NN";
    a[a["OO"] = 41] = "OO";
    a[a["PP"] = 42] = "PP";
    a[a["QQ"] = 43] = "QQ";
    a[a["RR"] = 44] = "RR";
    a[a["SS"] = 45] = "SS";
    a[a["TT"] = 46] = "TT";
    a[a["UU"] = 47] = "UU";
    a[a["VV"] = 48] = "VV";
    a[a["WW"] = 49] = "WW";
    a[a["XX"] = 50] = "XX";
    a[a["YY"] = 51] = "YY";
    a[a["ZZ"] = 52] = "ZZ"
})(Unit || (Unit = {}));
var UNIT_MAX = Unit.ZZ;
var BigNumber = (function() {
    function a(c, b) {
        if (c === void 0) { c = 0 }
        if (b === void 0) { b = Unit.zero }
        this.data = {};
        if (c === 0) { this.data[Unit.zero] = 0; return }
        this.formatValue(c, b)
    }
    a.valueOf = function(g) { const h = parseFloat(g); if (h === 0 || isNaN(h) || !g) { return new a() } const c = g.replace(/[ ]+/g, ""); var d = new a(); var b = c.split(/[0-9.]+/g); var f = c.split(/[a-zA-Z]+/g); for (var e = 0; e < f.length; e++) { d.setField(parseFloat(f[e]) || 0, Unit[b[e + 1]] || Unit.zero) } return d };
    a.parse = function(d) {
        var c = new a();
        var f = JSON.parse(d);
        if (typeof(f) !== "object") { return c }
        var e = Unit.zero;
        for (var b in f) {
            if (!f.hasOwnProperty(b)) { continue }
            e = parseInt(b, 10);
            if (e >= Unit.zero && e <= UNIT_MAX) { c.data[b] = f[b] }
        }
        return c
    };
    a.normalize = function(f) {
        var e = new a();
        for (var i in f.data) { if (f.data.hasOwnProperty(i)) { e.add(f.data[i], parseInt(i, 10)) } }
        var c = 1;
        var g = 0;
        var b = Unit.zero;
        var j = 0,
            h = false;
        var k = e.unites();
        if (k.length <= 1) { return f.copy(e) }
        var d = k[k.length - 1] + 1;
        for (var i = k[0]; i < d; i++) {
            if (i >= UNIT_MAX) { break }
            if (e.data.hasOwnProperty(i)) {
                b = i;
                g = Math.abs(e.data[i]);
                c = g >= 0 ? 1 : -1;
                h = false;
                if (g >= UNIT_BASE) {
                    while (g >= UNIT_BASE) {
                        j = g - Math.floor(g / UNIT_BASE) * UNIT_BASE;
                        if (j != 0) {
                            if (h) { if (e.data.hasOwnProperty(b)) { e.data[b] += c * j } else { e.data[b] = c * j } } else {
                                e.data[b] = c * j;
                                h = true
                            }
                        }
                        g = Math.floor(g / UNIT_BASE);
                        b++;
                        if (b >= UNIT_MAX) { break }
                    }
                    if (e.data.hasOwnProperty(b)) { e.data[b] += c * g } else { e.data[b] = c * g }
                }
            }
        }
        f.copy(e)
    };
    a.prototype.value = function() { a.normalize(this); return JSON.stringify(this.data) };
    a.prototype.simpleValue = function() {
        a.normalize(this);
        var d = this.getMaxUnit();
        var b = this.data[d] || 0;
        var e = b.toFixed(2);
        if (d > Unit.zero && this.data.hasOwnProperty(d - 1)) {
            b += this.data[d - 1] / UNIT_BASE;
            e = b.toFixed(2)
        }
        var c = e.indexOf(".");
        if (c >= MAX_LEN) { e = e.substring(0, c) } else { e = e.substring(0, MAX_LEN + 1) }
        return "" + e + (d == Unit.zero ? "" : Unit[d])
    };
    a.prototype.toNumber = function() { a.normalize(this); var c = this.getMaxUnit(); var b = this.data[c] || 0; if (c > Unit.zero && this.data.hasOwnProperty(c - 1)) { b += this.data[c - 1] / UNIT_BASE } return Math.round(b * Math.pow(UNIT_BASE, c)) };
    a.prototype.toString = function() {
        this.zipValue();
        var d = "",
            b = 0;
        for (var c in this.data) { if (this.data.hasOwnProperty(c)) { b = parseInt(c, 10); if (b == Unit.zero) { d = "" + this.data[b] } else { d = "" + this.data[b] + Unit[b] + d } } }
        if (d.length == 0) { d = "0" }
        return d
    };
    a.prototype.add = function(b, c, d) { if (c === void 0) { c = Unit.zero } if (d === void 0) { d = false } return this.addNum(new a(b, c), d) };
    a.prototype.set = function(b, c) {
        if (c === void 0) { c = Unit.zero }
        this.data = {};
        this.data[c] = b
    };
    a.prototype.setField = function(b, c) {
        if (c === void 0) { c = Unit.zero }
        this.data[c] = b
    };
    a.prototype.getField = function(b) { if (b === void 0) { b = Unit.zero } return this.data[b] || 0 };
    a.prototype.addNum = function(b, d) { if (d === void 0) { d = false } for (var c in b.data) { if (this.data.hasOwnProperty(c)) { this.data[c] += b.data[c] } else { this.data[c] = b.data[c] } } if (d) { a.normalize(this) } return this };
    a.prototype.sub = function(b, c) { if (c === void 0) { c = Unit.zero } return this.addNum(new a(-b, c)) };
    a.prototype.subNum = function(b, c) { if (c === void 0) { c = false } return this.addNum(b.clone().negate(), c) };
    a.prototype.negate = function() { for (var b in this.data) { if (this.data.hasOwnProperty(b)) { this.data[b] = -this.data[b] } } return this };
    a.prototype.multipleSelf = function(b, c) {
        if (c === void 0) { c = false }
        this.copy(this.multiple(b, c));
        return this
    };
    a.prototype.multiple = function(c, e) { if (e === void 0) { e = false } var d = new a(); for (var b in this.data) { if (this.data.hasOwnProperty(b)) { d.addNum(c.clone().multiple2(this.data[b], parseInt(b, 10))) } } if (e) { a.normalize(d) } return d };
    a.prototype.multiple2 = function(d, c, f) { if (c === void 0) { c = Unit.zero } if (f === void 0) { f = false } var e = new a(); for (var b in this.data) { if (this.data.hasOwnProperty(b)) { e.add(this.data[b] * d, parseInt(b, 10) + c) } } if (f) { a.normalize(e) } return e };
    a.prototype.multiple2Self = function(c, b, d) {
        if (b === void 0) { b = Unit.zero }
        if (d === void 0) { d = false }
        this.copy(this.multiple2(c, b, d));
        return this
    };
    a.prototype.div = function(c, g) {
        if (g === void 0) { g = false }
        var f = c.getMaxUnit();
        var b = c.data[f];
        var e = 5;
        for (var d = f - 1; d >= Unit.zero; d--) {
            if (e-- <= 0) { break }
            if (c.data.hasOwnProperty(d)) {
                b += c.data[d] / UNIT_BASE
            }
        }
        return this.div2(b, f, g)
    };
    a.prototype.divSelf = function(c, g) { if (g === void 0) { g = false } var f = c.getMaxUnit(); var b = c.data[f]; var e = 5; for (var d = f - 1; d >= Unit.zero; d--) { if (e-- <= 0) { break } if (c.data.hasOwnProperty(d)) { b += c.data[d] / UNIT_BASE } } return this.div2Self(b, f, g) };
    a.prototype.div2 = function(c, b, d) { if (b === void 0) { b = Unit.zero } if (d === void 0) { d = false } if (c == 0) { console.error("big number div / 0"); return this } return this.multiple2(1 / c, -b, d) };
    a.prototype.div2Self = function(c, b, d) { if (b === void 0) { b = Unit.zero } if (d === void 0) { d = false } if (c == 0) { console.error("big number div / 0"); return this } return this.multiple2Self(1 / c, -b, d) };
    a.prototype.gt = function(b) { var d = this.clone().subNum(b, true); var c = d.getMaxUnit(); return d.getField(c) > 0 };
    a.prototype.equalTo0 = function() { this.zipValue(); if (Object.keys(this.data).length == 1 && this.data[Unit.zero] === 0) { return true } return false };
    a.prototype.gt0 = function() { a.normalize(this); var b = this.getMaxUnit(); return this.data[b] > 0 };
    a.prototype.clone = function() {
        var b = new a();
        Object.assign(b.data, this.data);
        return b
    };
    a.prototype.copy = function(b) {
        this.data = {};
        Object.assign(this.data, b.data)
    };
    a.prototype.zipValue = function() { for (var b in this.data) { if (this.data[b] == 0) { delete this.data[b] } } if (Object.keys(this.data).length == 0) { this.data[Unit.zero] = 0 } };
    a.prototype.getMaxUnit = function() { this.zipValue(); var b = this.unites(); return b.length <= 0 ? Unit.zero : b[b.length - 1] };
    a.prototype.unites = function() { return Object.keys(this.data).map(function(b) { return parseInt(b) }).sort(function(d, c) { return d >= c ? 1 : -1 }) };
    a.prototype.formatValue = function(j, e) {
        if (e === void 0) { e = Unit.zero }
        var g = j;
        var h = e;
        if (h > UNIT_MAX) { console.error("单位超长.") } else {
            if (h < Unit.zero) {
                var d = Unit.zero - h;
                g = g / Math.pow(UNIT_BASE, d);
                h = Unit.zero
            }
        }
        var c = g >= 0 ? 1 : -1;
        var f = g * c;
        var b = h;
        if (f >= UNIT_BASE) {
            var i = 0;
            while (f > UNIT_BASE) {
                if (b >= UNIT_MAX) { break }
                i = f % UNIT_BASE;
                if (i != 0) { this.data[b] = c * i }
                f = Math.floor(f / UNIT_BASE);
                b++
            }
            if (f != 0) { this.data[b] = c * f }
        } else {
            if (f < 1) {
                var i = 0;
                while (f < 1) {
                    if (b <= Unit.zero) { break }
                    f *= UNIT_BASE;
                    b--
                }
                if (f != 0) { this.data[b] = c * parseFloat(f.toFixed(2)) }
            } else { this.data[h] = g; return }
        }
    };
    return a
})();
module.exports.BigNumber = BigNumber;
module.exports.Unit = Unit;